package com.matt.controller.pad.cookbook;


import com.aliyun.openservices.shade.com.alibaba.fastjson.JSONArray;
import com.aliyun.openservices.shade.com.alibaba.fastjson.JSONObject;
import com.matt.commons.utils.DateUtil;
import com.matt.domain.cookbook.RecipeIngredients;
import com.matt.domain.cookbook.RecipeShow;
import com.matt.commons.dto.sso.StaffDTO;;
import com.matt.foundation.dto.cookbook.*;
import com.matt.foundation.model.MemVerificationCache;
import com.matt.commons.model.StatusResponse;
import com.matt.foundation.utils.CookbookUtils;
import com.matt.service.cookbook.*;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.matt.foundation.constant.RequestConstant.TICKET;

@Controller
@RequestMapping("/pad/recipe")
public class PadCookBookController  {

    @Autowired
    private RecipeService recipeService;

    @Autowired
    private RecipeIngredientsService recipeIngredientsService;

    @Autowired
    private RecipeShowService recipeShowService;

    @Autowired
    private MemVerificationCache cache;

    private String dateToStr(Date date, String pattern){
        LocalDateTime time = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
        return time.format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 获取某周的健康食谱信息
     * @param ticket
     * @param startTime
     * @param endTime
     * @return
     */
	@ApiOperation(value = "获取某周的健康食谱信息",httpMethod = "POST")
    @RequestMapping("/week_health_recipe")
	public StatusResponse getWeekHealthRecipe(@RequestHeader(TICKET) String ticket,
                                              String startTime, String endTime){
//		GetWeekHealthRecipeReq req = RequestUtil.decode(request.getBody(),GetWeekHealthRecipeReq.class);
//		String startTime = req.getStartDate();
//		String endTime = req.getEndDate();
//		long schoolId = req.getSchoolId();
        String areaId = cache.getAreaId(ticket);

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("area_id", areaId);
		params.put("startTime", startTime);
		params.put("endTime", endTime);
		params.put("publishFlag", 1);

		Map rsp = new HashMap();

		List<RecipeShow> recipeShows = recipeShowService.selectRecipeListByCondition(params);
		List<DayRecipeDTO> weekRecipe = parseRecipeShowJson(recipeShows);

		rsp.put("weekRecipe", weekRecipe);

        //营养成分
		List<RecipeIngredients> ingredientsList = recipeIngredientsService.selectRecipeIngredientsByCondition(params);
		List<FoodIngredientsDTO> FoodIngredients = parseRecipeIngredientsJson(ingredientsList);
		rsp.put("ingredients", FoodIngredients);

		return StatusResponse.success(rsp);
	}

	public List<FoodIngredientsDTO> parseRecipeIngredientsJson(List<RecipeIngredients> list) {
		if (list == null || list.isEmpty())
			return null;

		List<FoodIngredientsDTO> ingredientsList = new ArrayList<FoodIngredientsDTO>();
		RecipeIngredients ingredients = list.get(0);
		JSONArray jsonIngredients = JSONArray.parseArray(ingredients.getIngredientsJson());
		if (jsonIngredients != null) {
			for (int i = 0; i < jsonIngredients.size(); i++) {
				JSONObject jsonElement = jsonIngredients.getJSONObject(i);
                FoodIngredientsDTO foodIngredients = new FoodIngredientsDTO();
				foodIngredients.setName(jsonElement.getString("elementName"));
				foodIngredients.setUnit(jsonElement.getString("elementUnit"));
				foodIngredients.setRefValue(jsonElement.getString("elementStandard"));
				foodIngredients.setResult(jsonElement.getString("schoolSupply"));
				foodIngredients.setExplain(jsonElement.getString("rankExplain"));

				JSONArray recommenditions = jsonElement.getJSONArray("recommendition");
				if (recommenditions != null) {
					List<FoodRecommendDTO> recommendFoods = new ArrayList<FoodRecommendDTO>();
					for (int j = 0; j < recommenditions.size(); j++) {
						JSONObject jsonFood = recommenditions.getJSONObject(j);
                        FoodRecommendDTO food = new FoodRecommendDTO();
						food.setName(jsonFood.getString("ingredientName"));
						food.setRank(jsonFood.getString("rank"));

						recommendFoods.add(food);
					}
					foodIngredients.setRecommendFoods(recommendFoods);
				}
				ingredientsList.add(foodIngredients);
			}
		}

		return ingredientsList;
	}

	public List<DayRecipeDTO> parseRecipeShowJson(List<RecipeShow> recipeShows) {
		if (recipeShows == null || recipeShows.isEmpty())
			return null;

		List<DayRecipeDTO> weekRecipe = new ArrayList<DayRecipeDTO>();
		for (RecipeShow recipeShow : recipeShows) {
            DayRecipeDTO dayRecipe = new DayRecipeDTO();
			List<MealRecipeDTO> meals = new ArrayList<MealRecipeDTO>();
			dayRecipe.setMealRecipe(meals);
			dayRecipe.setDate(recipeShow.getRecipeDate().getTime());
			dayRecipe.setINQ(10);
			JSONArray jsonMeals = JSONArray.parseArray(recipeShow.getContent());
			if (jsonMeals == null || jsonMeals.isEmpty())
				break;
			for (int i = 0; i < jsonMeals.size(); i++) {
				JSONObject jsonMeal = jsonMeals.getJSONObject(i);
                MealRecipeDTO mealRecipe = new MealRecipeDTO();
				String mealName = jsonMeal.getString("mealname");
				mealRecipe.setType(mealName);
				List<FoodDTO> foods = new ArrayList<FoodDTO>();
				mealRecipe.setFoodList(foods);
				JSONArray jsonFoods = jsonMeal.getJSONArray("menus");
				for (int j = 0; j < jsonFoods.size(); j++) {
					JSONObject jsonFood = jsonFoods.getJSONObject(j);
                    FoodDTO food = new FoodDTO();
					food.setFoodId((jsonFood.getLongValue("menuId")));
					String iconURl = jsonFood.getString("menuImageUrl");
					food.setIconURL(iconURl == null ? StringUtils.EMPTY : iconURl);
					food.setName(jsonFood.getString("menuName"));
					food.setType("");

					foods.add(food);
				}

				meals.add(mealRecipe);
			}

			weekRecipe.add(dayRecipe);
		}

		return weekRecipe;
	}

    /**
     * 获取某周的食谱信息
     * @param ticket
     * @param weekIndex
     * @return
     */
	@ApiOperation(value = "获取某周的食谱信息",httpMethod = "POST")
    @RequestMapping("/week_recipe_ext")
	public StatusResponse getWeekRecipeExt(@RequestHeader(TICKET) String ticket, int weekIndex){
        StaffDTO staff = cache.getStaff(ticket);
        String areaId = staff.getAreaId();

		//修改学校ID从user中获取

		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.WEEK_OF_YEAR, 0 - weekIndex);

		Date nowDate = calendar.getTime();

		Date weekMonday = DateUtil.getWeekMonday(nowDate);  //查询周星期一的日期
		Date weekSunday = DateUtil.getWeekSunday(nowDate, 0); //查询周的星期天的日期

		String startTime = dateToStr(weekMonday, CookbookUtils.DEFINE_YYYY_MM_DD );
                // com.talkyun.apus.util.DateUtil.formatDate2Str(weekMonday, com.talkyun.apus.util.DateUtil.DEFINE_YYYY_MM_DD);
		String endTime = dateToStr(weekSunday, CookbookUtils.DEFINE_YYYY_MM_DD );
                //com.talkyun.apus.util.DateUtil.formatDate2Str(weekSunday, com.talkyun.apus.util.DateUtil.DEFINE_YYYY_MM_DD);

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("area_id", areaId);
		params.put("startTime", startTime);
		params.put("endTime", endTime);

		LinkedHashSet<String> dayList = CookbookUtils.buildDayList(startTime, endTime);

		List<Map<String, Object>> list = recipeService.selectRecipeFoodByTime(params);

		Map rsp = new HashMap();
		List<DayRecipeDTO> dayRecipeList = null;
		dayRecipeList = wrapMapList2DayRecipeList(list,dayList);

		rsp.put("weekRecipe",dayRecipeList);
		rsp.put("startDate", weekMonday);
		rsp.put("endDate", weekSunday);

		return StatusResponse.success(rsp);

	}

	/**
	 * 获取当周的食谱信息
	 * @param ticket
	 * @return
	 */

	@ApiOperation(value = "获取当周的食谱信息",httpMethod = "POST")
	@RequestMapping("/week_recipe")
	public StatusResponse getWeekRecipe(@RequestHeader(TICKET) String ticket){

		String areaId = cache.getAreaId(ticket);

		Calendar nowCalendar = Calendar.getInstance();
		Date nowDate = nowCalendar.getTime();

		Date currentWeekMonday = DateUtil.getWeekMonday(nowDate);  //当前周星期一的日期
		Date currentWeekSunday = DateUtil.getWeekSunday(nowDate, 0); //当前周的星期天的日期
		String startTime = CookbookUtils.dateToStr(currentWeekMonday, CookbookUtils.DEFINE_YYYY_MM_DD);
				// com.talkyun.apus.util.DateUtil.formatDate2Str(currentWeekMonday, com.talkyun.apus.util.DateUtil.DEFINE_YYYY_MM_DD);
		String endTime = CookbookUtils.dateToStr(currentWeekSunday, CookbookUtils.DEFINE_YYYY_MM_DD);
				//com.talkyun.apus.util.DateUtil.formatDate2Str(currentWeekSunday, com.talkyun.apus.util.DateUtil.DEFINE_YYYY_MM_DD);

		LinkedHashSet<String> dayList = CookbookUtils.buildDayList(startTime, endTime);

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("area_id", areaId);
		params.put("startTime", startTime);
		params.put("endTime", endTime);
		List<Map<String, Object>> list = recipeService.selectRecipeFoodByTime(params);

		List<DayRecipeDTO> dayRecipeList = wrapMapList2DayRecipeList(list,dayList);

		return StatusResponse.success(dayRecipeList);
	}


	/**
	 * 将List<Map<String,Object>> 封装成 List<DayRecipe>
	 * @param recipeMapList
	 * @return
	 */
	public List<DayRecipeDTO> wrapMapList2DayRecipeList(List<Map<String,Object>> recipeMapList , LinkedHashSet<String> dayList){
		List<DayRecipeDTO> dayRecipeList = new ArrayList<DayRecipeDTO>();
		if(recipeMapList == null || recipeMapList.size() == 0)
			return dayRecipeList;

		LinkedHashMap<String,LinkedHashMap<String, List<LinkedHashMap<String, Object>>>> cookBookMap
																						= builderFoodMap(recipeMapList);

		//按天迭代一周的数据
		for (String dayDateStr : dayList) {
			//一天的餐次数据集
			LinkedHashMap<String, List<LinkedHashMap<String, Object>>> mealMap = cookBookMap.get(dayDateStr);
			Date dayDate = DateUtil.parseToPattern(dayDateStr, CookbookUtils.DEFINE_YYYY_MM_DD);
			DayRecipeDTO dayRecipe = new DayRecipeDTO();
			dayRecipe.setDate(dayDate.getTime());
			dayRecipe.setINQ(10); //暂时没有用到该字段

			List<MealRecipeDTO> mealRecipeList = new ArrayList<MealRecipeDTO>();

			if(mealMap != null){
				//迭代一天的餐次数据
				for (String meal : mealMap.keySet()) {
					List<LinkedHashMap<String, Object>> foodMapList = mealMap.get(meal);
					MealRecipeDTO mealRecipe = new MealRecipeDTO();
					mealRecipe.setType(meal);
					List<FoodDTO> foodList = new ArrayList<FoodDTO>();
					//迭代一个餐次的食物数据
					for (Map<String, Object> foodMap : foodMapList) {

						Long foodId = Long.parseLong(foodMap.get("foodId").toString());
						String foodName = String.valueOf(foodMap.get("foodName"));
						String photo = String.valueOf(foodMap.get("photo"));
						String foodType = String.valueOf(foodMap.get("foodType"));
						String typeName = String.valueOf(foodMap.get("typeName"));

						FoodDTO food = new FoodDTO();
						food.setFoodId(foodId);
						food.setIconURL(photo);
						food.setName(foodName);
						food.setType(typeName);

						foodList.add(food);
					}
					mealRecipe.setFoodList(foodList);
					mealRecipeList.add(mealRecipe);
				}
			}
			dayRecipe.setMealRecipe(mealRecipeList);
			dayRecipeList.add(dayRecipe);
		}

		return dayRecipeList;
	}



	/**
	 * 封装天次的数据集
	 * @param recipeMapList
	 * @return
	 */
	public LinkedHashMap<String,LinkedHashMap<String, List<LinkedHashMap<String, Object>>>>
										builderDayMap(List<Map<String,Object>> recipeMapList){

		LinkedHashMap<String, LinkedHashMap<String, List<LinkedHashMap<String, Object>>>> result
			= new LinkedHashMap<String,LinkedHashMap<String,List<LinkedHashMap<String,Object>>>>();

		for (Map<String, Object> map : recipeMapList) {
			String recipeDate = String.valueOf(map.get("recipe_date"));
			result.put(recipeDate, null);
		}

		return result;
	}

	/**
	 * 封装餐次的数据集
	 * @param recipeMapList
	 * @return
	 */
	public LinkedHashMap<String,LinkedHashMap<String, List<LinkedHashMap<String, Object>>>>
												builderMealMap(List<Map<String,Object>> recipeMapList){

		LinkedHashMap<String, LinkedHashMap<String, List<LinkedHashMap<String, Object>>>>
															result = builderDayMap(recipeMapList);

		for (String key : result.keySet()) {

			LinkedHashMap<String, List<LinkedHashMap<String, Object>>> mealMap
								= new LinkedHashMap<String, List<LinkedHashMap<String,Object>>>();
			for (Map<String, Object> map : recipeMapList) {
				String recipeDate = String.valueOf(map.get("recipe_date"));
				String recipeTypeName = String.valueOf(map.get("recipe_type_name"));
				//如果餐次时间和当前迭代的天日期一致
				if(recipeDate.equals(key)){
					mealMap.put(recipeTypeName, null);
				}
			}
			result.put(key, mealMap);
		}

		return result;
	}

	/**
	 * 封装按天次-餐次-食物集合
	 * @param recipeMapList
	 * @return
	 */
	public LinkedHashMap<String,LinkedHashMap<String, List<LinkedHashMap<String, Object>>>>
														builderFoodMap(List<Map<String,Object>> recipeMapList){

		LinkedHashMap<String, LinkedHashMap<String, List<LinkedHashMap<String, Object>>>> result = builderMealMap(recipeMapList);

		//迭代天的数据
		for(String dayKey : result.keySet()){
			LinkedHashMap<String, List<LinkedHashMap<String, Object>>> mealMap = result.get(dayKey);

			//迭代餐次的数据
			for (String mealKey : mealMap.keySet()) {
				List<LinkedHashMap<String, Object>> foodList = new ArrayList<LinkedHashMap<String,Object>>();

				//迭代查询出来的数据进行匹对
				for (Map<String, Object> map : recipeMapList) {
					String recipeDate = String.valueOf(map.get("recipe_date"));
					String recipeTypeName = String.valueOf(map.get("recipe_type_name"));

					//同一天并且是同一个餐次
					if(dayKey.equals(recipeDate) && mealKey.equals(recipeTypeName)){

						LinkedHashMap<String, Object> foodMap = new LinkedHashMap<String, Object>();
						String foodId = String.valueOf(map.get("food_id"));
						String foodName = String.valueOf(map.get("food_name"));
						String photo = map.get("photo") == null ? StringUtils.EMPTY : map.get("photo").toString();
						String foodType = String.valueOf(map.get("food_type"));
						String typeName = String.valueOf(map.get("type_name"));

						foodMap.put("foodId", foodId);
						foodMap.put("foodName", foodName);
						foodMap.put("photo", photo);
						foodMap.put("foodType", foodType);
						foodMap.put("typeName", typeName);

						foodList.add(foodMap);
					}
				}
				mealMap.put(mealKey, foodList);
			}
			result.put(dayKey, mealMap);
		}

		return result;
	}

}
